package com.edushare.common.dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.cayenne.DataObjectUtils;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.SelectQuery;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.edushare.common.constants.ApplicationConstants;
import com.edushare.common.exceptions.EduShareRuntimeException;
import com.edushare.common.exceptions.MoveFolderException;
import com.edushare.common.orm.ORMInterface;
import com.edushare.common.vo.CourseInstances;
import com.edushare.common.vo.Departments;
import com.edushare.common.vo.Enrolments;
import com.edushare.common.vo.FileDirTypes;
import com.edushare.common.vo.FileDirectories;
import com.edushare.common.vo.Groups;
import com.edushare.common.vo.Universities;
import com.edushare.common.vo.UserDeptLink;
import com.edushare.common.vo.UserRoles;
import com.edushare.common.vo.Users;
import com.edushare.common.vo.interfaces.IFileUploadable;

public class FileDirectoriesDAO extends CayenneBasedDAO {
	
	private static Log log = LogFactory.getLog(FileDirectoriesDAO.class);

	public FileDirectoriesDAO(ORMInterface ormInterface) {
		super(ormInterface);
	}
	
	/**
	 * DO NOT EXPOSE THIS METHOD PUBLICLY
	 * creates a root directory at L0
	 * @param uploadable
	 * @return root directory
	 */
	private FileDirectories createRootDir(IFileUploadable uploadable) {
		FileDirTypes fdType = new FileDirTypesDAO(ormInterface).getFileDirTypes(FileDirTypes.ROOT_DIR);
		FileDirectories fd = getDataContext().newObject(FileDirectories.class);
		fd.setDirectoryName("Root");
		fd.setOwnerId(uploadable.getObjectPrimaryKey());
		fd.setOwnerType(uploadable.getObjectType().getIntVal());
		fd.setReadPerm(fdType.getDefaultReadPerm());
		fd.setDirType(fdType);
		fd.setLevel(0);//The ONLY L0 Directory
		fd.setCreationTimestamp(new Date());
		getDataContext().commitChanges(); 
		return fd;
	}

	
	/**
	 * gets the root directory for an entity
	 * @param uplodable
	 * @return returns root directory -- the top level (L0) of directory
	 */
	public FileDirectories getOrCreateRootDir(IFileUploadable uploadable){
		
		FileDirectories rootDir = null;
		
		//1. see if the directory exists
		List<FileDirectories> fds = this.getAllDirectories(uploadable, FileDirTypes.ROOT_DIR);
		if(fds!=null && fds.size()>0){
			if(fds.size()>1){
				log.warn("MORE THAN ONE DIRECTORY EXISTS FOR: [ownerType: " +uploadable.getObjectType().getIntVal() +
						", ownerId: "+ uploadable.getObjectPrimaryKey() +
						", directoryType:"+ FileDirTypes.ROOT_DIR +"]");
			}
			
			rootDir = fds.get(0);
		}
		//2. Else create a new root directory
		else{
			rootDir = createRootDir(uploadable);
		}
		
		return rootDir;
	}

	/**
	 * returns all directories of certain types owned by iFileUploadable.
	 * Note, it returns all files of a type irrespective to levels
	 * @param uploadable
	 * @param fileDirType
	 * @return List of all fileDirectories of a type for given owner object (IFileUploadable object)
	 */
	@SuppressWarnings("unchecked")
	public List<FileDirectories> getAllDirectories(IFileUploadable uploadable, String fileDirType) {
		
		FileDirTypes dirType = new FileDirTypesDAO(ormInterface).getFileDirTypes(fileDirType);
		Expression exp = Expression.fromString("" +
						"ownerType = $ownertype and " +
						"ownerId = $ownerid and " +
						"dirType = $dirtype");
		HashMap params = new HashMap();
		params.put("ownertype", uploadable.getObjectType().getIntVal());
		params.put("ownerid", uploadable.getObjectPrimaryKey());
		params.put("dirtype", dirType);
		
		SelectQuery query = new SelectQuery(FileDirectories.class, exp.expWithParameters(params));
		List<FileDirectories> fds = (List<FileDirectories>)getDataContext().performQuery(query);
		return fds;
	}
	
	/**
	 * @param fileDirType
	 * @return list of directories of a given type irrespective to the owner id and type
	 */
	@SuppressWarnings("unchecked")
	public List<FileDirectories> getAllDirectoriesByType(String fileDirType) {
		
		FileDirTypes dirType = new FileDirTypesDAO(ormInterface).getFileDirTypes(fileDirType);
		Expression exp = Expression.fromString("dirType = $dirtype");
		HashMap params = new HashMap();
		params.put("dirtype", dirType);
		
		SelectQuery query = new SelectQuery(FileDirectories.class, exp.expWithParameters(params));
		List<FileDirectories> fds = (List<FileDirectories>)getDataContext().performQuery(query);
		return fds;
	}

	/**
	 * Creates default and system directories should be used internally
	 * @param dirName
	 * @param uploadable
	 * @param fileDirType
	 * @return System or default directory of type mentioned
	 */
	private FileDirectories getOrCreateSystemDirectory(String dirName, IFileUploadable uploadable, String fileDirType){
		FileDirectories systemDir = null;
		
		List<FileDirectories> fds = this.getAllDirectories(uploadable, fileDirType);
		if(fds!=null && fds.size()>0){
			if(fds.size()>1){
				log.warn("MORE THAN ONE DIRECTORY EXISTS FOR: [ownerType: " +uploadable.getObjectType().getIntVal() +
						", ownerId: "+ uploadable.getObjectPrimaryKey() +
						", directoryType:"+ fileDirType +"]");
			}
			//hopefully there are only one default dir, if more just pick one that's at L1
			for(FileDirectories fd: fds){
				systemDir = fd;
				if(fd.getLevel()==1)
					break;
			}
		}
		else{
			systemDir = this.createNewSystemDirectory(dirName, getOrCreateRootDir(uploadable), fileDirType);
		}
			
		return systemDir;
	}
	
	/**
	 * Creates a new directory at a level one below the parent directory keeping ownerId and type same as parent
	 * @param dirName
	 * @param parent
	 * @param fileDirType
	 * @return child of certain type
	 */
	private FileDirectories createNewSystemDirectory(String dirName, FileDirectories parent, String fileDirType){
		if(parent.getLevel() >= ApplicationConstants.MAX_DIR_DEPTH)
			throw new EduShareRuntimeException("Max Directory depth is reached... you can't create a directory below this");
		FileDirTypes fdType = new FileDirTypesDAO(ormInterface).getFileDirTypes(fileDirType);
		FileDirectories fd = getDataContext().newObject(FileDirectories.class);
		fd.setDirectoryName(dirName);
		fd.setOwnerId(parent.getOwnerId());
		fd.setOwnerType(parent.getOwnerType());
		fd.setReadPerm(fdType.getDefaultReadPerm());
		fd.setDirType(fdType);
		fd.setParent(parent);
		fd.setLevel(parent.getLevel()+1);
		fd.setCreationTimestamp(new Date());
		fd.setUpdateTimestamp(new Date());
		getDataContext().commitChanges(); 
		return fd;
	}

	

	/**
	 * Assumes that permission is set in fd,
	 * @param fd
	 * @param parentDir
	 * @param fileDirType
	 * @return
	 */
	public FileDirectories createNewDir(FileDirectories fd, FileDirectories parentDir, String fileDirType) {
		if(parentDir.getLevel() >= ApplicationConstants.MAX_DIR_DEPTH)
			throw new EduShareRuntimeException("Max Directory depth is reached... you can't create a directory below this");
		FileDirTypes fdType = new FileDirTypesDAO(ormInterface).getFileDirTypes(fileDirType);
		getDataContext().registerNewObject(fd);
		fd.setOwnerId(parentDir.getOwnerId());
		fd.setOwnerType(parentDir.getOwnerType());
//		fd.setPermission(fdType.getDefaultPerm());
		fd.setDirType(fdType);
		fd.setParent(parentDir);
		fd.setLevel(parentDir.getLevel()+1);
		fd.setCreationTimestamp(new Date());
		fd.setUpdateTimestamp(new Date());
		getDataContext().commitChanges(); 
		return fd;
	}
	
	
	/** gets if there is one in database else creates one */
	public FileDirectories getOrCreateDefaultDirectory(IFileUploadable uploadable){
		return this.getOrCreateSystemDirectory("Profile Directory",uploadable, FileDirTypes.DEFAULT_DIR);
	}
	
	/** gets if there is one in database else creates one */
	public FileDirectories getOrCreateDefaultGallery(IFileUploadable uploadable){
		return this.getOrCreateSystemDirectory("Profile Gallery", uploadable, FileDirTypes.DEFAULT_GALLERY);
	}
	
	/**
	 * System temp directory is single directory for the whole SYSTEM.
	 * The files under it can be deleted from Admin Console
	 * @param uploadable
	 * @return
	 */
	public FileDirectories getOrCreateSystemTempDir(IFileUploadable uploadable){
		FileDirectories fd = null;
		List<FileDirectories> systemDirList = getAllDirectoriesByType(FileDirTypes.SYSTEM_TEMP);
		if(systemDirList!=null && systemDirList.size()>0){
			if(systemDirList.size()>1){
				log.warn("MORE THAN ONE TEMP DIRECTORY EXISTS!");
			}
			fd = systemDirList.get(0);
		}else{
			FileDirTypes fdType = new FileDirTypesDAO(ormInterface).getFileDirTypes(FileDirTypes.SYSTEM_TEMP);
			fd = getDataContext().newObject(FileDirectories.class);
			fd.setDirectoryName("System Temp");
			fd.setOwnerId(uploadable.getObjectPrimaryKey());
			fd.setOwnerType(uploadable.getObjectType().getIntVal());
			fd.setReadPerm(fdType.getDefaultReadPerm());
			fd.setDirType(fdType);
			fd.setLevel(0);//The ONLY L0 Directory
			fd.setCreationTimestamp(new Date());
			getDataContext().commitChanges(); 
		}
		
		return fd;
	}
	
	/** Deletes all the files from disk, all the files from DB and directory from DB */
	public void deleteDirectoryAndFiles(FileDirectories fileDir){
		new FilesUploadedDAO(ormInterface).deleteFiles(fileDir.getFilesUploaded());
		getDataContext().deleteObject(fileDir);
		getDataContext().commitChanges();
	}
	
	/**
	 * cascade delete of all the directories and files below this.
	 * Note:: This is a recursive process!!
	 * @param fd
	 */
	private void deleteDirectory(FileDirectories fd){
		
		if(fd.getChildren()==null || fd.getChildren().size()<1){
			deleteDirectoryAndFiles(fd);
		}else{
			Iterator<FileDirectories> it = fd.getChildren().iterator(); 
			while(it.hasNext()){
				FileDirectories fddelete = it.next();
				it.remove();
				this.deleteDirectory(fddelete);
			}
		}
		
		
	}

	/** 
	 * creates temp directory with anonymous owner.
	 * NOTE: THE DIRECTORIES WITH ANONYMOUS OWNER GETS FLUSHED AFTER 24 HR, SO PLEASE MAKE SURE YOU ASSIGN A OWNER IF YOU WANT TO AVOID DELETION
	 * Deletion mechanism is there so that if a user uploads and then cancels before creating owner object like in case of assignments, this helps in keeping tidy data and files 
	 * @param tempDirId
	 * @return FileDirectory with tempId
	 */
	public FileDirectories getOrCreateTempDirectory(String tempDirId) {
		
		FileDirectories dir = getTempDirectory(tempDirId);
		
		if(dir==null){
			dir = getDataContext().newObject(FileDirectories.class);
			dir.setTempDirId(tempDirId);
			dir.setCreationTimestamp(new Date());
			dir.setUpdateTimestamp(new Date());
			getDataContext().commitChanges();
		}

		return dir;
	}
	
	/**
	 * Gets directory based on tempId, must not be used if you have other means to retrieve this (like FileDirectoryId, ownerId-OwnerType
	 * @param tempDirId
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public FileDirectories getTempDirectory(String tempDirId){
		Expression exp = Expression.fromString(""+
		"tempDirId = $tempraryId");
		HashMap hm = new HashMap();
		hm.put("tempraryId", tempDirId);
		
		SelectQuery query = new SelectQuery(FileDirectories.class, exp.expWithParameters(hm));
		List<FileDirectories> fds = (List<FileDirectories>)getDataContext().performQuery(query);
		
		if(fds==null || fds.size() < 1){
			return null;
		}else{
			return fds.get(0);
		}

	}

	public void setDirType(FileDirectories fd, String dirType) {
		FileDirTypes type = new FileDirTypesDAO(ormInterface).getFileDirTypes(dirType);
		fd.setDirType(type);
		fd.setReadPerm(type.getDefaultReadPerm());
	}

	public void deleteDirectoryByTempId(String dirTempId) {
		FileDirectories fd = getTempDirectory(dirTempId);
		if(fd!=null){
			deleteDirectory(fd);
		}
	}

	/** moves a directory from one place to other, 
	 * throws exception if the folder is default or destination is at the last possible level
	 * @param dirToMove
	 * @param destination
	 * @throws MoveFolderException
	 */
	public void moveDirectory(FileDirectories dirToMove, FileDirectories destination) throws MoveFolderException{
		
		if(dirToMove.getDirType().getDirType().equals(FileDirTypes.DEFAULT_DIR) || 
				dirToMove.getDirType().getDirType().equals(FileDirTypes.DEFAULT_GALLERY)){
			throw new MoveFolderException("This is a default folder -- a system generated folder can't be moved");
		}
		
		if(destination.getLevel() >= ApplicationConstants.MAX_DIR_DEPTH){
			throw new MoveFolderException("The parent directory has reached maximum level of depth, more folders can't be added");
		}
		
		dirToMove.setParent(destination);
		dirToMove.setLevel(destination.getLevel()+1);
		ormInterface.commitAllChanges();
	}
	
	public List<FileDirectories> getChildren(FileDirectories dir, List<String> userVisibility) {
		Expression exp = Expression.fromString("parent = $parentDir ");
		
		Expression parentExp = ExpressionFactory.matchExp("parent", dir);
		
		List lstVisibility = new ArrayList();
		for(String visibility: userVisibility){
			lstVisibility.add(ExpressionFactory.matchExp("readPerm", visibility));
		}
		
		Expression qual = ExpressionFactory.joinExp(Expression.OR, lstVisibility);
		qual = qual.andExp(parentExp);
		
		SelectQuery query = new SelectQuery(FileDirectories.class, qual);

		return getDataContext().performQuery(query);
	}

	public FileDirectories getFileDirById(int fileDirId) {
		return DataObjectUtils.objectForPK(getDataContext(),FileDirectories.class, fileDirId);
	}

	public void updateFolderAndSubfolderVisibility(FileDirectories dir, String newVisibility) {
		List<String> avlVis = FileDirectories.getAllPermissions(dir.getOwnerType());//this list is arranged from top to bottom in decreasing scope
		HashMap<String, Integer> hm = new HashMap<String, Integer>();
		
		int curIndex = -1;
		int finalIndex = -1;
		for(int i=0; i<avlVis.size(); i++){
			if(avlVis.get(i).equals(dir.getReadPerm())){
				curIndex = i;
			}
			if(avlVis.get(i).equals(newVisibility)){
				finalIndex = i;
			}
			//create map for update function
			hm.put(avlVis.get(i), i);
		}
		
		//if they both are valid then only chnage
		if(curIndex>-1 && finalIndex>-1){
			if(finalIndex < curIndex){ //increasing scope
				updateDirScopeOnly(dir, newVisibility);
			}else if(finalIndex > curIndex){ // decreasing scope
				updateDirScopeOnly(dir, newVisibility);
				updateAllSubDirScope(dir, newVisibility, hm);
			}
		}
		
		getDataContext().commitChanges();
	}

	/**
	 * Recursively DESCOPES all sub directories and current directory if they are eligible.. 
	 * i.e. their scope is wider than parent's final scope
	 * @param dir
	 * @param newVisibility
	 * @param a hashmap that has key as two-lettered scope code and it's index from FileDirectories class
	 * 
	 */
	private void updateAllSubDirScope(FileDirectories dir, String newVisibility, HashMap<String, Integer> visIndexMap) {
		
		if(visIndexMap.get(newVisibility)>visIndexMap.get(dir.getReadPerm())){
			dir.setReadPerm(newVisibility);
		}
		if(dir.getChildren()!=null && dir.getChildren().size()>0){
			for(FileDirectories fd: dir.getChildren()){
				updateAllSubDirScope(fd, newVisibility, visIndexMap);
			}
		}
	}

	private void updateDirScopeOnly(FileDirectories dir, String newVisibility) {
		dir.setReadPerm(newVisibility);
	}

	public List<Users> getAccessingUserList(FileDirectories directory){
		String perm = directory.getReadPerm();
		if(		perm.equalsIgnoreCase(FileDirectories.PERM_PUBLIC) || 
				perm.equalsIgnoreCase(FileDirectories.PERM_UNIV_STUDENTS)
		){
			Universities u = getAssociatedUniversity(directory);
			Expression exp = Expression.fromString("roleList.status = $stts and roleList.university = $univ");
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("stts", UserRoles.STATUS_ACTIVE);
			params.put("univ", u);
			SelectQuery query = new SelectQuery(Users.class, exp.expWithParameters(params));
			return getDataContext().performQuery(query);
			
		}else if(
				perm.equalsIgnoreCase(FileDirectories.PERM_UNIV_TEACHER)
		){
			Universities u = getAssociatedUniversity(directory);
			Expression exp = Expression.fromString("roleList.roleType = $role and roleList.status = $stts and roleList.university = $univ");
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("role", UserRoles.TEACHER_ROLE);
			params.put("stts", UserRoles.STATUS_ACTIVE);
			params.put("univ", u);
			SelectQuery query = new SelectQuery(Users.class, exp.expWithParameters(params));
			return getDataContext().performQuery(query);
			
		}else if(
				perm.equalsIgnoreCase(FileDirectories.PERM_UNIV_ADMIN)
		){
			Universities u = getAssociatedUniversity(directory);
			Expression exp = Expression.fromString("roleList.roleType = $role and roleList.status = $stts and roleList.university = $univ");
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("role", UserRoles.ADMIN_ROLE);
			params.put("stts", UserRoles.STATUS_ACTIVE);
			params.put("univ", u);
			SelectQuery query = new SelectQuery(Users.class, exp.expWithParameters(params));
			return getDataContext().performQuery(query);
			
		}else if(
				perm.equalsIgnoreCase(FileDirectories.PERM_DEPT_STUDENT)
		){
			Departments d = getAssociatedDepartment(directory);
			Expression exp = Expression.fromString(
					"departmentLinks.status = $stts and " +
					"departmentLinks.departmentLink = $dept");
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("stts", UserDeptLink.STATUS_ACTIVE);
			params.put("dept", d);
			SelectQuery query = new SelectQuery(Users.class, exp.expWithParameters(params));
			return getDataContext().performQuery(query);
			
		}else if(
				perm.equalsIgnoreCase(FileDirectories.PERM_DEPT_TEACHER)
		){
			Departments d = getAssociatedDepartment(directory);
			Expression exp = Expression.fromString(
					"departmentLinks.roleType = $role and " +
					"departmentLinks.status = $stts and " +
					"departmentLinks.departmentLink = $dept");
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("role", UserDeptLink.TEACHER);
			params.put("stts", UserDeptLink.STATUS_ACTIVE);
			params.put("dept", d);
			SelectQuery query = new SelectQuery(Users.class, exp.expWithParameters(params));
			return getDataContext().performQuery(query);
			
		}else if(
				perm.equalsIgnoreCase(FileDirectories.PERM_DEPT_ADMIN)
		){
			Departments d = getAssociatedDepartment(directory);
			Expression exp = Expression.fromString(
					"departmentLinks.roleType = $role and " +
					"departmentLinks.status = $stts and " +
					"departmentLinks.departmentLink = $dept");
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("role", UserDeptLink.PRIMARY_ADMIN);
			params.put("stts", UserDeptLink.STATUS_ACTIVE);
			params.put("dept", d);
			SelectQuery query = new SelectQuery(Users.class, exp.expWithParameters(params));
			return getDataContext().performQuery(query);
			
		}else if(
				perm.equalsIgnoreCase(FileDirectories.PERM_COURSE_STUDENT)
		){
			CourseInstances c = getAssociatedCourseInstance(directory);
			Expression exp = Expression.fromString(
										"enrolments.status = $stts and " +
										"enrolments.courseInstance = $cinst");
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("stts", Enrolments.ENROLLED);
			params.put("cinst", c);
			SelectQuery query = new SelectQuery(Users.class, exp.expWithParameters(params));
			return getDataContext().performQuery(query);
			
		}else if(
				perm.equalsIgnoreCase(FileDirectories.PERM_COURSE_TEACHER)
		){
			CourseInstances c = getAssociatedCourseInstance(directory);
			Expression exp = Expression.fromString(
											"enrolments.enrolmentType = $role and " +
											"enrolments.status = $stts and " +
											"enrolments.courseInstance = $cinst");
			HashMap<String, Object> params = new HashMap<String, Object>();
			params.put("role", Enrolments.TEACHER);
			params.put("stts", Enrolments.ENROLLED);
			params.put("cinst", c);
			SelectQuery query = new SelectQuery(Users.class, exp.expWithParameters(params));
			return getDataContext().performQuery(query);
		}else if(
				perm.equalsIgnoreCase(FileDirectories.PERM_GROUP_MEMBERS)
		){
			Groups g = getAssociatedGroup(directory);
			return new UsersDAO(ormInterface).getGroupMembers(g);
		}
		return null;
	}

	private Groups getAssociatedGroup(FileDirectories directory) {
		return new GroupsDAO(ormInterface).getGroupById(directory.getOwnerId());
	}

	private CourseInstances getAssociatedCourseInstance(FileDirectories directory) {
		if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.COURSE_INSTANCE.getIntVal()){
			return new CourseInstancesDAO(ormInterface)
						.getCourseInstanceById(directory.getOwnerId());
		}
		return null;
	}

	private Departments getAssociatedDepartment(FileDirectories directory) {
		if(directory.getOwnerType()==FileDirectories.DIRECTORY_OWNER_TYPE.DEPARTMENT.getIntVal()){
			return new DepartmentsDAO(ormInterface).getDepartmentByPk(directory.getOwnerId());
		}else if(directory.getOwnerType()==FileDirectories.DIRECTORY_OWNER_TYPE.COURSE_INSTANCE.getIntVal()){
			CourseInstances c = new CourseInstancesDAO(ormInterface).getCourseInstanceById(directory.getOwnerId());
			return c.getCourse().getDeptLinks().get(0).getDepartment();
		}
		return null;
	}

	private Universities getAssociatedUniversity(FileDirectories directory) {
		if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.UNIVERSITY.getIntVal()){
			return new UniversitiesDAO(ormInterface).getUnivById(directory.getOwnerId());
		}else if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.DEPARTMENT.getIntVal()){
			Departments d = new DepartmentsDAO(ormInterface).getDepartmentByPk(directory.getOwnerId());
			return d.getUnivLinks().get(0).getUniversity();
		}else if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.COURSE_INSTANCE.getIntVal()){
			CourseInstances ci = new CourseInstancesDAO(ormInterface).getCourseInstanceById(directory.getOwnerId());
			return ci.getCourse().getUniversities().get(0).getUniversity();
		}else if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.GROUP.getIntVal()){
			return new GroupsDAO(ormInterface).getGroupById(directory.getOwnerId()).getUniversity();
		}
		
		return null;
	}

	public IFileUploadable getOwnerObject(FileDirectories directory) {
		if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.UNIVERSITY.getIntVal()){
			return new UniversitiesDAO(ormInterface).getUnivById(directory.getOwnerId());
		}else if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.DEPARTMENT.getIntVal()){
			return new DepartmentsDAO(ormInterface).getDepartmentByPk(directory.getOwnerId());
		}else if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.COURSE_INSTANCE.getIntVal()){
			return new CourseInstancesDAO(ormInterface).getCourseInstanceById(directory.getOwnerId());
		}else if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.USER.getIntVal()){
			return new UsersDAO(ormInterface).getUserByPk(directory.getOwnerId());
		}else if(directory.getOwnerType() == FileDirectories.DIRECTORY_OWNER_TYPE.GROUP.getIntVal()){
			return new GroupsDAO(ormInterface).getGroupById(directory.getOwnerId());
		}
		return null;
	}
}
